#define _WIN32_DCOM
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include "component\component.h"

DWORD g_threadid = 0;
int cancel = 0;

void __stdcall MyThread(DWORD nothing)
{
	HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if(FAILED(hr))
		cout << "CoInitializeEx failed" << endl;

//	hr = CoCancelCall(g_threadid, 0);

	ICancelMethodCalls* pCancelMethodCalls = 0;
	hr = CoGetCancelObject(g_threadid, IID_ICancelMethodCalls, (void**)&pCancelMethodCalls);
//	    printf("Call CoGetCancelObject hr =  %0x\n", hr);

	cout << endl << "Canceling the call" << endl;

	hr = pCancelMethodCalls->Cancel(0);
	pCancelMethodCalls->Release();
	if(hr == CO_E_CANCEL_DISABLED)
	{
//		#define CO_E_CANCEL_DISABLED             _HRESULT_TYPEDEF_(0x80010140L)

	    printf("Call cancellation CO_E_CANCEL_DISABLED %0x\n", hr);
		exit(0);
	}

	CoUninitialize();
}

void main()
{
    HRESULT hr;

	hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if(FAILED(hr))
        cout << "CoInitializeEx failed. " << endl;

	IPrime* pPrime = 0;
	hr = CoCreateInstance(CLSID_InsideCOM, 0, CLSCTX_LOCAL_SERVER, IID_IPrime, (void**)&pPrime);
	if(FAILED(hr))
	    cout << "CoCreateInstance FAILED" << endl;

	g_threadid = GetCurrentThreadId();
	DWORD newthread = 0;

	CoEnableCallCancellation(0);

	for(int testnumber = 1000000; testnumber < 1001000; testnumber++)
	{
		int result = 0;

		if(++cancel > 75)
		{
			HANDLE thread_handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)MyThread, 0, 0, &newthread);
			cancel = 0;
		}

		hr = pPrime->IsPrime(testnumber, &result);

		if(hr == RPC_E_CALL_CANCELED)
			cout << "RPC_E_CALL_CANCELED The call really was cancelled" << endl;
		else if(FAILED(hr))
		    printf("IsPrime FAILED hr = %0x\n", hr);
		else if(SUCCEEDED(hr))
			if(result)
				cout << endl << testnumber << " is prime." << endl;
		}

	pPrime->Release();

    CoUninitialize();
}